package com.numberone.framework.shiro.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.numberone.common.constant.Constants;
import com.numberone.common.constant.ShiroConstants;
import com.numberone.common.constant.UserConstants;
import com.numberone.common.enums.UserStatus;
import com.numberone.common.exception.user.CaptchaException;
import com.numberone.common.exception.user.UserBlockedException;
import com.numberone.common.exception.user.UserDeleteException;
import com.numberone.common.exception.user.UserNotExistsException;
import com.numberone.common.exception.user.UserPasswordNotMatchException;
import com.numberone.common.utils.DateUtils;
import com.numberone.common.utils.MessageUtils;
import com.numberone.common.utils.ServletUtils;
import com.numberone.framework.manager.AsyncManager;
import com.numberone.framework.manager.factory.AsyncFactory;
import com.numberone.framework.util.ShiroUtils;
import com.numberone.system.domain.SysUser;
import com.numberone.system.service.ISysUserService;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.util.Hashtable;

/**
 * 登录校验方法
 * 
 * @author numberone
 */
@Component
public class SysLoginService
{
    @Autowired
    private SysPasswordService passwordService;

    @Autowired
    private ISysUserService userService;

    /**
     * 登录
     */
    public SysUser login(String username, String password)
    {
        // 验证码校验
        if (!StringUtils.isEmpty(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA)))
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
            throw new CaptchaException();
        }
        String userName = username;//AD域认证，用户的登录UserName
        String passWord = password;//AD域认证，用户的登录PassWord
        String host = "10.1.3.7";//AD域IP，必须填写正确
        String domain = "@osmglobal.com";//域名后缀，例.@noker.cn.com
        String port = "389"; //端口，一般默认389
        String url = new String("ldap://" + host + ":" + port);//固定写法
        String user2 = userName.indexOf(domain) > 0 ? userName : userName
                + domain;//网上有别的方法，但是在我这儿都不好使，建议这么使用
        Hashtable env = new Hashtable();//实例化一个Env
        DirContext ctx = null;
        env.put(Context.SECURITY_AUTHENTICATION, "simple");//LDAP访问安全级别(none,simple,strong),一种模式，这么写就行
        env.put(Context.SECURITY_PRINCIPAL, user2); //用户名
        env.put(Context.SECURITY_CREDENTIALS, passWord);//密码
        env.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.jndi.ldap.LdapCtxFactory");// LDAP工厂类
        env.put(Context.PROVIDER_URL, url);//Url
        boolean flag=false;
        try {
            ctx = new InitialDirContext(env);// 初始化上下文
            System.out.println("身份验证成功!");
            flag=true;
        } catch (AuthenticationException e) {
            System.out.println("身份验证失败!");
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
            e.printStackTrace();

        } catch (javax.naming.CommunicationException e) {
            System.out.println("AD域连接失败!");
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("身份验证未知异常!");
            e.printStackTrace();
        } finally{
            if(null!=ctx){
                try {
                    ctx.close();
                    ctx=null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        if(flag){
            //验证成功
            System.out.println("域登录验证成功！");
            //域登录验证成功之后获取用户名保存进数据库
            SysUser userAD = new SysUser();
            userAD.setLoginName(userName);
            userAD.setUserName(userName);
            if(userService.selectUserByLoginName(userName) == null){
                userService.insertUser(userAD);
            }else{
                System.out.println("用户已存在！");
            }
        }else{
            //验证失败
            System.out.println("域登录验证失败！");
        }

//        // 用户名或密码为空 错误
//        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
//        {
//            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
//            throw new UserNotExistsException();
//        }
//        // 密码如果不在指定范围内 错误
//        if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
//                || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
//        {
//            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
//            throw new UserPasswordNotMatchException();
//        }
//
//        // 用户名不在指定范围内 错误
//        if (username.length() < UserConstants.USERNAME_MIN_LENGTH
//                || username.length() > UserConstants.USERNAME_MAX_LENGTH)
//        {
//            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
//            throw new UserPasswordNotMatchException();
//        }

        // 查询用户信息
        SysUser user = userService.selectUserByLoginName(username);
        if(user == null){
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
            throw new UserNotExistsException();
        }
//        if (user == null && maybeMobilePhoneNumber(username))
//        {
//            user = userService.selectUserByPhoneNumber(username);
//        }

//        if (user == null && maybeEmail(username))
//        {
//            user = userService.selectUserByEmail(username);
//        }

//        if (user == null)
//        {
//            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
//            throw new UserNotExistsException();
//        }

//        if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
//        {
//            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.delete")));
//            throw new UserDeleteException();
//        }

//        if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
//        {
//            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark())));
//            throw new UserBlockedException();
//        }

//        passwordService.validate(user, password);
//
//        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
//        recordLoginInfo(user);

        return user;
    }

    private boolean maybeEmail(String username)
    {
        if (!username.matches(UserConstants.EMAIL_PATTERN))
        {
            return false;
        }
        return true;
    }

    private boolean maybeMobilePhoneNumber(String username)
    {
        if (!username.matches(UserConstants.MOBILE_PHONE_NUMBER_PATTERN))
        {
            return false;
        }
        return true;
    }

    /**
     * 记录登录信息
     */
    public void recordLoginInfo(SysUser user)
    {
        user.setLoginIp(ShiroUtils.getIp());
        user.setLoginDate(DateUtils.getNowDate());
        userService.updateUserInfo(user);
    }
}
